/*
-----------------------------------------------------------------------------
This file is part of NxGraphics, Multimedia Engine.
Author : Stephane Kyles. Developed in Prague, Czech Republic.
				_   __       ____               _           
			   / | / /_  __ / __ \ ___  _   __ (_)_____ ___ 
			  /  |/ /| |/_// / / // _ \| | / // // ___// _ \
			 / /|  /_>  < / /_/ //  __/| |/ // // /__ /  __/
			/_/ |_//_/|_|/_____/ \___/ |___//_/ \___/ \___/ 
			                                                
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#ifndef __NXDEVICEPrerequisites_H__
#define __NXDEVICEPrerequisites_H__

#include "NxDevice_DLL.h"
#include <windows.h>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cstdarg>
#include <cmath>

// STL containers
#include <vector>
#include <map>
#include <string>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <bitset>
#include <iostream>
#include <fstream>

//#include <atlbase.h>



#define MIDI_CLOCK      0xf8
#define MIDI_ACTIVE     0xfe
#define MIDI_STATUS_MASK 0x80
#define MIDI_SYSEX      0xf0
#define MIDI_EOX        0xf7
#define MIDI_START      0xFA
#define MIDI_STOP       0xFC
#define MIDI_CONTINUE   0xFB
#define MIDI_F9         0xF9
#define MIDI_FD         0xFD
#define MIDI_RESET      0xFF
#define MIDI_NOTE_ON    0x90
#define MIDI_NOTE_OFF   0x80
#define MIDI_CHANNEL_AT 0xD0
#define MIDI_POLY_AT    0xA0
#define MIDI_PROGRAM    0xC0
#define MIDI_CONTROL    0xB0
#define MIDI_PITCHBEND  0xE0
#define MIDI_MTC        0xF1
#define MIDI_SONGPOS    0xF2
#define MIDI_SONGSEL    0xF3
#define MIDI_TUNE       0xF6




typedef void NxMidiStream;
typedef enum {
    NxMidiNoError = 0,
    NxMidiNoData = 0, /* A "no error" return that also indicates no data avail. */
    NxMidiGotData = 1, /* A "no error" return that also indicates data available */
    NxMidiHostError = -10000,
    NxMidiInvalidDeviceId, /* out of range or 
                        * output device when input is requested or 
                        * input device when output is requested or
                        * device is already opened 
                        */
    NxMidiInsufficientMemory,
    NxMidiBufferTooSmall,
    NxMidiBufferOverflow,
    NxMidiBadPtr,
    NxMidiBadData, /* illegal midi data, e.g. missing EOX */
    NxMidiInternalError,
    NxMidiBufferMaxSize /* buffer is already as large as it can be */
    /* NOTE: If you add a new error type, be sure to update Pm_GetErrorText() */
} NxMidiError;

typedef long NxMidiTimestamp;
typedef long NxMidiMessage;
typedef struct 
{
    NxMidiMessage message;
    NxMidiTimestamp timestamp;
} NxMidiEvent;


#if defined( _MSC_VER )
// Turn off warnings generated by long std templates
// This warns about truncation to 255 characters in debug/browse info
#   pragma warning (disable : 4786)

// Turn off warnings generated by long std templates
// This warns about truncation to 255 characters in debug/browse info
#   pragma warning (disable : 4503)

// disable: "conversion from 'double' to 'float', possible loss of data
#   pragma warning (disable : 4244)

// disable: "truncation from 'double' to 'float'
#   pragma warning (disable : 4305)

// disable: "<type> needs to have dll-interface to be used by clients'
// Happens on STL member variables which are not public therefore is ok
#   pragma warning (disable : 4251)

// disable: "non dll-interface class used as base for dll-interface class"
// Happens when deriving from Singleton because bug in compiler ignores
// template export
#   pragma warning (disable : 4275)

// disable: "C++ Exception Specification ignored"
// This is because MSVC 6 did not implement all the C++ exception
// specifications in the ANSI C++ draft.
#   pragma warning( disable : 4290 )

// disable: "no suitable definition provided for explicit template
// instantiation request" Occurs in VC7 for no justifiable reason on all
// #includes of Singleton
#   pragma warning( disable: 4661)

// disable: deprecation warnings when using CRT calls in VC8
// These show up on all C runtime lib code in VC8, disable since they clutter
// the warnings with things we may not be able to do anything about (e.g.
// generated code from nvparse etc). I doubt very much that these calls
// will ever be actually removed from VC anyway, it would break too much code.
#	pragma warning( disable: 4996)

// disable: "conditional expression constant"
#   pragma warning (disable : 201)

#endif


class MTRand;

namespace KVANT
{
	class KvantLib ;

} 

namespace NxDevice_Namespace {

class NxDevice_Hardware ;
class NxDeviceMidi ;
class NxMidiManager ;


struct NxDevice3DConnexionInst;

struct NxDeviceDmxUtil;
class NxDeviceDmx;

struct NxDeviceTrackIrInst;
class NxDeviceTrackIr;

struct NxDeviceWiimoteInst;
class NxDeviceWiimote;

class NxDeviceOscListener;
class NxDeviceOsc;
class NxDeviceOscMessages;

class NxDeviceManager;



enum NxWiimoteMask
{
	LEFT	= 0x0001,
	RIGHT	= 0x0002,
	DOWN	= 0x0004,
	UP		= 0x0008,
	PLUS	= 0x0010,
	TWO		= 0x0100,
	ONE		= 0x0200,
	_B		= 0x0400,
	_A		= 0x0800,
	MINUS	= 0x1000,
	HOME	= 0x8000,
	ALL		= LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME,
};






template <typename T> class NxDevice_Export Singleton
{
	public:
	  static T* ms_Singleton;
        Singleton( void )
        {
			assert( !ms_Singleton );
			#if defined( _MSC_VER ) && _MSC_VER < 1200	 
            int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
			ms_Singleton = (T*)((int)this + offset);
			#else
			ms_Singleton = static_cast< T* >( this );
			#endif
        }

        ~Singleton( void )
		{  
			assert( ms_Singleton );
			ms_Singleton = 0;  
		}

        static T& getSingleton( void )
		{	
			assert( ms_Singleton );
			return ( *ms_Singleton );
		}

        static T* getSingletonPtr( void )
		{ 
			return ms_Singleton;
		}
    };
}

#endif
